//
//  CCVSCustomView.m
//  ClinicalCollections
//
//  Created by Pasirstein, David B on 4/5/13.
//  Copyright (c) 2013 GOPI. All rights reserved.
//


#import "CCVSCustomView.h"

#import "CCVSCommon.h"
#import "CCVSCustomTypes.h"
#import "CCVSColumn.h"

@implementation CCVSCustomView 
@synthesize topics = _topics;
@synthesize details = _details;
@synthesize superView = _superView;
@synthesize vc = _vc;

@synthesize leftRightDivisor = _leftRightDivisor;

static float lrDivisor = 3.0f;


-(void)setSuperView:(UIView *)superView
{
    _superView = superView;
}

-(void)setLeftRightDivisor:(float)leftRightDivisor
{
    lrDivisor = leftRightDivisor;
    _leftRightDivisor = leftRightDivisor;
}

-(float)leftRightDivisor
{
    if (!_leftRightDivisor) _leftRightDivisor = lrDivisor;
    return _leftRightDivisor;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

//return the width of the label that would be contained in the topic's view
+(CGFloat)getTopicLabelWidth:(CGFloat)superViewFrameWidth
{
    return [CCVSCustomView getTopicViewWidth:superViewFrameWidth] - CCVS_BOARDERSIZE;
}

//return the width of the label the would be contained in the detail's view
+(CGFloat)getDetailLabelWidth:(CGFloat)superViewFrameWidth
{
    return [CCVSCustomView getDetailViewWidth:superViewFrameWidth] - CCVS_BOARDERSIZE;
}

//return the topic's view (not label) width provided a superView such as a cell
+(CGFloat)getTopicViewWidth:(CGFloat)superViewFrameWidth
{
    //left size is 1/3 and right side will be 2/3
    CGFloat divider = [CCVSCustomView getLeftRightDivider:superViewFrameWidth];
    return divider - (CCVS_BOARDERSIZE * 1.5);
}

//return the detail's view (not label) width provided a superView such as a cell
+(CGFloat)getDetailViewWidth:(CGFloat)superViewFrameWidth
{
    //left size is 1/3 and right side will be 2/3
    CGFloat divider = [CCVSCustomView getLeftRightDivider:superViewFrameWidth];
    divider = superViewFrameWidth - divider;
    return divider - (CCVS_BOARDERSIZE * 1.5);
}

//consistent way to determine the left/right split point
+(CGFloat)getLeftRightDivider:(CGFloat)superViewFrameWidth
{
    //default is left size is 1/3 and right side will be 2/3
    return superViewFrameWidth / lrDivisor;
}


-(void) buildView
{
    CGFloat prevYLoc = CCVS_BOARDERSIZE;
    
    if ((id)self.details != [NSNull null] &&
        (id)self.topics != [NSNull null] &&
        ([self.details count] == [self.topics count])) {
        
        //left size is 1/3 and right side will be 2/3
        CGFloat divider = [CCVSCustomView getLeftRightDivider:self.superView.frame.size.width];
        
        
        //for each row...
        for (int i = 0; i<[self.topics count]; i++) {
            
            CGSize sizeTopic,sizeDetail;
            sizeTopic.width = [CCVSCustomView getTopicViewWidth:self.superView.frame.size.width];
            sizeDetail.width = [CCVSCustomView getDetailViewWidth:self.superView.frame.size.width];
            
            //how large should the subview be
            //we want the topic and detail to be the same height so we want the
            //MAX of the two for that row
            CGFloat height = MAX([CCVSCustomView calcSizeOfLabel:self.topics[i]
                                                  withLabelWidth:sizeTopic.width].height,
                                 [CCVSCustomView calcSizeOfLabel:self.details[i]
                                                  withLabelWidth:sizeDetail.width].height)
            + CCVS_BOARDERSIZE*2;  // *2 for top and bottom
            
            sizeTopic.height = height;
            sizeDetail.height = height;
            
            UIView * subView1 = [self createCustomSubView:sizeTopic
                                                yLocation:prevYLoc
                                                xLocation:CCVS_BOARDERSIZE
                                                 withData:self.topics[i]];
            
            //create the detail subview
            UIView * subView2 = [self createCustomSubView:sizeDetail
                                                yLocation:prevYLoc
                                                xLocation:divider+(CCVS_BOARDERSIZE*0.5)
                                                 withData:self.details[i]];
            
            
            //Update the Y location so we know where to place the next subview in the loop
            //...ie. where to start the next row
            prevYLoc = prevYLoc + height + CCVS_BOARDERSIZE;
            
            //add the subviews (topic and detail) to the subview for this row
            [self.superView addSubview:subView1];
            [self.superView addSubview:subView2];
            
        }
    } else if ((id)self.topics != [NSNull null]) {
        CGSize sizeTopic;
        sizeTopic.width = self.superView.frame.size.width - CCVS_BOARDERSIZE*2;
        //we only have topics
        for (int i = 0; i<[self.topics count]; i++) {
            sizeTopic.height = [CCVSCustomView calcSizeOfLabel:self.topics[i]
                                                withLabelWidth:sizeTopic.width].height +
            CCVS_BOARDERSIZE*2;
            UIView * subView1 = [self createCustomSubView:sizeTopic
                                                yLocation:prevYLoc
                                                xLocation:CCVS_BOARDERSIZE
                                                 withData:self.topics[i]];
            
            //Update the Y location so we know where to place the next subview in the loop
            //...ie. where to start the next row
            prevYLoc = prevYLoc + sizeTopic.height + CCVS_BOARDERSIZE;
            
            //add the subviews (topic and detail) to the subview for this row
            [self.superView addSubview:subView1];
            
        } //end for loop
    }
}


-(UIView *)createCustomSubView:(CGSize)size yLocation:(CGFloat)yLocation xLocation:(CGFloat)xLocation withData:(id)data
{
    UIView * subView1 = [[CCVSCustomView alloc] initWithFrame:CGRectMake(xLocation, yLocation, size.width, size.height)];
    subView1.layer.backgroundColor = [UIColor whiteColor].CGColor;
    //subView1.layer.masksToBounds = YES; //this will disable 3d effect
    
    subView1.layer.cornerRadius = 5.0;
    subView1.layer.borderColor = [UIColor lightGrayColor].CGColor;
    subView1.layer.borderWidth = 1.5f;
    subView1.layer.shadowColor = [UIColor blackColor].CGColor;
    subView1.layer.shadowOpacity = 0.8;
    subView1.layer.shadowRadius = 3.0;
    subView1.layer.shadowOffset = CGSizeMake(2.0, 2.0);
    
    ////
    //Question: what if the detail actually contains another level
    //of topic and details.  Then instead of a label, we should embed
    //another CCVSCustomView
    if ([data isKindOfClass:[NSArray class]]) {
        CCVSCustomView * newCustomView = [[CCVSCustomView alloc] init];
        newCustomView.vc = self.vc;
        newCustomView.superView = subView1;
        newCustomView.topics = data[0];
        newCustomView.details = data[1];
        [newCustomView buildView];

    } else if ([data isKindOfClass:[NSString class]]) {
        //if here, we have an NSString to display
        /////////////////////
        //Now we create the detail label
        UILabel * label1 = [self createLabelForView:data inView:subView1];
        
        [subView1 addSubview:label1]; //add the topic label to the subview
    } else if ([data conformsToProtocol:@protocol(CCVSCustomDataType)]) {
        //if we are here, we have something more complex than an NSString; therefore,
        //we expect it to conform to the CustomDataType protocol
        
        //Custom Data Type Objects must specific the name of the object the can
        //render it in a view.  So, we get that NSString of and we load it
        //as a Class
        Class<CCVSCustomViewType> myCustomSubViewClass = NSClassFromString(((id<CCVSCustomDataType>)data).customViewType);

        //We calculate the frame
        CGRect frame = CGRectMake(CCVS_BOARDERSIZE, CCVS_BOARDERSIZE,
                                  subView1.frame.size.width-CCVS_BOARDERSIZE,
                                  [myCustomSubViewClass
                                   calcViewHeight:subView1.frame.size.width-CCVS_BOARDERSIZE
                                   fromObject:data].height);

        //We alloc and init the view class as an in memory object        
        id<CCVSCustomViewType> view =
             [(id<CCVSCustomViewType>)[(Class)myCustomSubViewClass alloc]
                                          initWithData:data
                                             withFrame:frame
                                        viewController:self.vc];
        //We now instruct the view to render
        UIView * v = [view buildView];
        //And we add it to this view
        [subView1 addSubview:v];
    }

    
    return subView1;
}

//Creates the label...note if this is a hyperlink, the label is actually
//a CCSV Extended Label
-(UILabel*)createLabelForView:(id)data inView:(UIView*)subView1
{
    UILabel * label1;
    NSString * text;
        //we have a regular label
        label1 = [[UILabel alloc] initWithFrame:
                  CGRectMake(CCVS_BOARDERSIZE, CCVS_BOARDERSIZE,
                             subView1.frame.size.width-CCVS_BOARDERSIZE,
                             [CCVSCustomView calcSizeOfLabel:data withLabelWidth:subView1.frame.size.width-CCVS_BOARDERSIZE].height)];
        text = ((NSString*)data);
    label1.backgroundColor = [UIColor clearColor];
    label1.numberOfLines = 0;
    label1.lineBreakMode = NSLineBreakByWordWrapping;
    label1.font = [UIFont fontWithName:@CCVS_FONTNAME size:CCVS_FONTSIZE];
    
    //add the data to the label
    label1.text = text;
    
    return label1;
}


//note: you probably want the calcSiteOfLabel method instead of this one
//for most cases.
//this will calculate the total height given both a topic array and
//detail array by adding the MAX height of each per row and adding
//in space for the boarder
+(CGSize)calcSizeOfLabelFromArray:(NSArray *)topic withDetail:(NSArray*)detail withLabelWidth:(CGFloat)width
{
    CGSize size = CGSizeMake(0, 0);
    CGFloat topicWidth = [CCVSCustomView getTopicLabelWidth:width];
    CGFloat detailWidth = [CCVSCustomView getDetailViewWidth:width];
    //
    if ((id)topic != [NSNull null]) {
        for(int i = 0; i < [topic count]; i++) {
            if (((id)topic != [NSNull null]) && ((id)detail != [NSNull null])) {
                //if we have both a topic and detail list, then we want
                //the max of the two
                size.height += MAX([CCVSCustomView calcSizeOfLabel:topic[i]
                                                    withLabelWidth:topicWidth].height,
                                   [CCVSCustomView calcSizeOfLabel:detail[i]
                                                    withLabelWidth:detailWidth].height);
                size.height += CCVS_BOARDERSIZE*2;
            } else if ((id)topic != [NSNull null]) {
                //else if we only have a topic list
                //then we want that, but our base width is the full width
                size.height += [CCVSCustomView calcSizeOfLabel:topic[i]
                                                withLabelWidth:width].height;
                size.height += CCVS_BOARDERSIZE*2;
            }
        }
    }
    return size;
}

//This will calculate the size/height of a label given "data", where
//text can be either NSString or NSArray of size 2 (NSArray Topic,NSArray Detail)
+(CGSize)calcSizeOfLabel:(id)data withLabelWidth:(CGFloat)width
{
    CGSize size = CGSizeMake(0, 0);
    //if we have a string, then we simply calculate based on the size of the string
    //since CCVSHyperLink inherits from NSString...this should be all thats needed
    if ([data isKindOfClass:[NSString class]]) {
        size = [data sizeWithFont:[UIFont fontWithName:@CCVS_FONTNAME size:CCVS_FONTSIZE]
                constrainedToSize:CGSizeMake(width, 9999)
                    lineBreakMode:NSLineBreakByWordWrapping];
    } else if ([data conformsToProtocol:@protocol(CCVSCustomDataType)]) {
        //We have a custom data type that conforms to our protocol
        //we need to load the view class specified in the data object
        Class<CCVSCustomViewType> view = NSClassFromString(((id<CCVSCustomDataType>)data).customViewType);
        //call the class method specified in the custom view protocol
        size = [view calcViewHeight:width fromObject:data];
    } else if ([data isKindOfClass:[NSArray class]]) {
        //we have an array, so we need to calculate based on the array
        //we probably have a BUG here, because the arrays in details, could have
        //left and right sides
        size = [self calcSizeOfLabelFromArray:data[0]
                                   withDetail:data[1]
                               withLabelWidth:width-CCVS_BOARDERSIZE];
        size.height += CCVS_BOARDERSIZE*2;
    }
    return size;
}

-(void)removeFromSuperview
{
    self.topics = nil;
    self.details = nil;
    self.superView = nil;
    self.vc = nil;
    [self cleanUpCustomViews];
    [super removeFromSuperview];
}

//Re-use of this cell could happen do to a change
//or the cell could be recycled.  If this happens
//we need to clean up as we don't want the old subviews
//and related data sticking around
-(void)cleanUpCustomViews
{
    for (int i = [self.subviews count]-1; i>0; i--) {
        [self.subviews[i] removeFromSuperview];
    }
}



/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

@end
